from django.contrib.auth import get_user_model
from rest_framework import serializers

from .models import Sprint, Task

User = get_user_model()


class UserSerializer(serializers.ModelSerializer):
    full_name = serializers.CharField(source='get_full_name', read_only=True)

    class Meta:
        model = User
        fields = ('id', User.USERNAME_FIELD, 'full_name', 'is_active')


class SprintSerializer(serializers.ModelSerializer):
    class Meta:
        model = Sprint
        fields = ('id', 'name', 'description', 'end_at')

    def validate_end(self, attrs, source):
        end_date = attrs[source]
        new = not self.object
        changed = self.object and self.object.end_at != end_date
        if (new or changed) and (end_date < date.today()):
            msg = _('End date cannot be in the past.')
            raise serializers.ValidationError(msg)
        return attrs


class TaskSerializer(serializers.ModelSerializer):
    assigned_to = serializers.SlugRelatedField(
        slug_field=User.USERNAME_FIELD, required=False, read_only=True)
    status_display = serializers.SerializerMethodField()

    def get_status_display(self, obj):
        return obj.get_status_display()

    class Meta:
        model = Task
        fields = ('id', 'name', 'description', 'sprint', 'status_display',
                  'order_no', 'assigned_to', 'started_at', 'due_at', 'completed_at')

    def validate_sprint(self, attrs, source):
        sprint = attrs[source]
        if self.object and self.object.pk:
            if sprint != self.object.sprint:
                if self.object.status == Task.STATUS_DONE:
                    msg = _('Cannot change the sprint of a completed task.')
                    raise serializers.ValidationError(msg)
                if sprint and sprint.end_at < date.today():
                    msg = _('Cannot assign tasks to past sprints.')
                    raise serializers.ValidationError(msg)
        else:
            if sprint and sprint.end_at < date.today():
                msg = _('Cannot add tasks to past sprints.')
                raise serializers.ValidationError(msg)
        return attrs
    def validate(self,attrs):
        sprint = attrs.get('sprint')
        status = int(attrs.get('status'))
        started_at = attrs.get('started_at')
        completed_at = attrs.get('completed_at')
        if not sprint and status != Task.STATUS_TODO:
            msg = _("Backlog tasks must have 'Not Started' status.")
            raise serializers.ValidationError(msg)
        if started_at and status == Task.STATUS_TODO:
            msg = _('Started date cannot be set for not started tasks.')
            raise serializers.ValidationError(msg)
        if completed_at and status != Task.STATUS_DONE:
            msg = _('Completed date cannot be set for uncompleted tasks.')
            raise serializers.ValidationError(msg)
        return attrs